package com.share.starter.sharding.config;

import com.share.starter.sharding.rule.BbtJdRuleConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.shardingsphere.api.config.rule.ShardingRuleConfiguration;
import io.shardingsphere.api.config.rule.TableRuleConfiguration;
import io.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Administrator
 * @data 2019/6/10
 */

@Configuration
@MapperScan(basePackages = "com.tydic.bbt.*.dao.sharding", sqlSessionTemplateRef = "shardingSqlSessionTemplate")
public class ShardingDataSourceConfig {
	@Autowired
	private Sharding0Properties sharding0;

	@Autowired
	private Sharding1Properties sharding1;

	@Bean("shardingDataSource")
	public DataSource dsDataSource() throws SQLException {
		// 配置真实数据源
		Map<String, DataSource> dataSourceMap = new HashMap<>();
		HikariDataSource ds0 = new HikariDataSource();
		ds0.setJdbcUrl(sharding0.getUrl());
		ds0.setUsername(sharding0.getUsername());
		ds0.setPassword(sharding0.getPassword());
		ds0.setDriverClassName(sharding0.getDriverClassName());
		dataSourceMap.put("ds0", ds0);

		HikariDataSource ds1 = new HikariDataSource();
		ds1.setJdbcUrl(sharding1.getUrl());
		ds1.setUsername(sharding1.getUsername());
		ds1.setPassword(sharding1.getPassword());
		ds1.setDriverClassName(sharding1.getDriverClassName());
		dataSourceMap.put("ds1", ds1);

		// 注册配置
		ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
		Collection<TableRuleConfiguration> ruleConfig = shardingRuleConfig.getTableRuleConfigs();
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_nopay","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_rate","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_afterpay","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_send_delay","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_send","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_trade_track","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_jd_member","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_record","seller_nick",String.class,"seller_nick",String.class,2,2).config());

		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_pay_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_secondary_pay_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_arrive_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_wait_send_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_delay_send_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_send_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_receive_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());
		ruleConfig.add(new BbtJdRuleConfig("bbt_remind_rate_temp","seller_nick",String.class,"seller_nick",String.class,2,2).config());

		return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new ConcurrentHashMap(),new Properties());
	}

	@Bean("shardingSqlSessionFactory")
	public SqlSessionFactory shardingSqlSessionFactory(@Qualifier("shardingDataSource") DataSource dataSource)
			throws Exception {
		SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
		bean.setDataSource(dataSource);
		bean.setMapperLocations(
				new PathMatchingResourcePatternResolver().getResources("classpath:mapper/sharding/*.xml"));
		bean.setConfigLocation(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis.cfg.xml"));
		return bean.getObject();
	}

	@Bean("shardingSqlSessionTemplate")
	public SqlSessionTemplate shardingSqlSessionTemplate(
			@Qualifier("shardingSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	@Bean("shardingTransactionManager")
	public DataSourceTransactionManager shardingTransactionManager(
			@Qualifier("shardingDataSource") DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}
}
